package com.youlai.system.service.impl;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youlai.system.common.base.BaseQuery;
import com.youlai.system.common.base.IBaseEnum;
import com.youlai.system.common.enums.DegreeEnum;
import com.youlai.system.common.util.DateUtils;
import com.youlai.system.mapper.SysExamMapper;
import com.youlai.system.model.entity.SysDegree;
import com.youlai.system.model.entity.SysExam;
import com.youlai.system.model.entity.SysPeriod;
import com.youlai.system.model.query.ExamPageQuery;
import com.youlai.system.model.vo.*;
import com.youlai.system.service.SysDegreeService;
import com.youlai.system.service.SysExamService;
import com.youlai.system.service.SysPeriodService;
import com.youlai.system.service.SysScoreService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 考试名单业务处理实现
 */
@Service
@RequiredArgsConstructor
public class SysExamServiceImpl extends ServiceImpl<SysExamMapper, SysExam> implements SysExamService {

    private final SysPeriodService periodService;

    private final SysDegreeService degreeService;

    private final SysScoreService scoreService;

    @Override
    public SysExam getExam(Long studentId, Long courseId) {
        LambdaQueryWrapper<SysExam> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysExam::getStudentId, studentId).eq(SysExam::getCourseId, courseId);
        return getOne(queryWrapper);
    }

    @Override
    public boolean clearExamBy(Long studentId, Long courseId) {
        LambdaQueryWrapper<SysExam> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysExam::getStudentId, studentId).eq(SysExam::getCourseId, courseId);
        return remove(queryWrapper);
    }

    @Override
    public boolean clearExamByCourseId(Long courseId) {
        LambdaQueryWrapper<SysExam> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysExam::getCourseId, courseId);
        return remove(queryWrapper);
    }

    @Override
    public IPage<ExamPageVO> getExamPage(ExamPageQuery queryParams) {
        // 参数构建
        int pageNum = queryParams.getPageNum();
        int pageSize = queryParams.getPageSize();
        Page<ExamPageVO> page = new Page<>(pageNum, pageSize);

        // 格式化为数据库日期格式，避免日期比较使用格式化函数导致索引失效
        DateUtils.toDatabaseFormat(queryParams, "startTime", "endTime");

        // 查询数据
        Page<ExamPageVO> examPage = this.baseMapper.getExamPage(page, queryParams);
        examPage.getRecords().forEach(examPageVO -> {
            examPageVO.setCourseMonthStr(DateUtils.monthTranslate(examPageVO.getCourseMonth()));
            examPageVO.setHasEvaluateTimes(scoreService.countByStudentIdAndCourseId(examPageVO.getStudentId(), examPageVO.getCourseId()));
        });
        // 实体转换
        return examPage;
    }

    @Override
    public List<ExamPageVO> getExamList(ExamPageQuery queryParams) {
        // 格式化为数据库日期格式，避免日期比较使用格式化函数导致索引失效
        DateUtils.toDatabaseFormat(queryParams, "startTime", "endTime");
        List<ExamPageVO> examPageVOList = this.baseMapper.getExamList(queryParams);
        examPageVOList.forEach(examPageVO -> {
            examPageVO.setCourseMonthStr(DateUtils.monthTranslate(examPageVO.getCourseMonth()));
            examPageVO.setHasEvaluateTimes(scoreService.countByStudentIdAndCourseId(examPageVO.getStudentId(), examPageVO.getCourseId()));
        });
        return examPageVOList;
    }

    @Override
    public List<ExamDetailVO> getExamDetailList(Long examId) {
        SysExam exam = getById(examId);
        List<ExamDetailVO> examDetailVOList = new ArrayList<>();
        List<SysPeriod> periodList = periodService.getPeriodList(exam.getStudentId(), exam.getCourseId());
        periodList.forEach(period -> {
            ExamDetailVO examDetailVO = new ExamDetailVO();
            examDetailVO.setPeriod(period.getPeriod());
            examDetailVO.setDegree(period.getDegree());
            examDetailVO.setDegreeStr(IBaseEnum.getLabelByValue(period.getDegree(), DegreeEnum.class));
            examDetailVO.setScoreCount(period.getScoreCount());
            examDetailVO.setScoreList(period.getScoreList());
            examDetailVO.setLastTime(period.getLastTime());
            if (StrUtil.isNotBlank(period.getScoreList())) {
                List<ScorePageVO> scorePageVOList = scoreService.getScoreListByIdList(StrUtil.split(period.getScoreList(), StrUtil.COMMA).stream().map(Long::valueOf).collect(Collectors.toList()));
                examDetailVO.setChildren(scorePageVOList);
            }

            examDetailVOList.add(examDetailVO);
        });
        SysDegree degree = degreeService.getStuCourseDegree(exam.getStudentId(), exam.getCourseId());
        if (degree != null) {
            ExamDetailVO examDetailVO = new ExamDetailVO();
            examDetailVO.setPeriod(0);
            examDetailVO.setDegree(degree.getDegree());
            examDetailVO.setDegreeStr(IBaseEnum.getLabelByValue(degree.getDegree(), DegreeEnum.class));
            examDetailVO.setScoreCount(degree.getScoreCount());
            examDetailVO.setLastTime(degree.getLastTime());
            examDetailVO.setScoreList(degree.getScoreList());
            if (StrUtil.isNotBlank(degree.getScoreList())) {
                List<ScorePageVO> scorePageVOList = scoreService.getScoreListByIdList(StrUtil.split(degree.getScoreList(), StrUtil.COMMA).stream().map(Long::valueOf).collect(Collectors.toList()));
                examDetailVO.setChildren(scorePageVOList);
            }

            examDetailVOList.add(examDetailVO);
        }
        return examDetailVOList;
    }

    @Override
    public List<DegreeCountVO> getAllDegreeContList(BaseQuery baseQuery) {

        List<DegreeCountVO> degreeCountVOList = this.baseMapper.getAllDegreeContList(baseQuery);
        degreeCountVOList.forEach(degreeCountVO -> {
            String degreeName = IBaseEnum.getLabelByValue(degreeCountVO.getDegree(), DegreeEnum.class);
            degreeCountVO.setDegreeName(degreeName);
        });
        return degreeCountVOList;
    }

    @Override
    public List<DeptDegreeCountVO> getDeptDegreeCountList() {
        List<DeptDegreeCountVO> deptDegreeCountVOList = this.baseMapper.getDeptDegreeCountList();
        deptDegreeCountVOList.forEach(deptDegreeCountVO -> {
            Double aPercent = Double.valueOf(NumberUtil.decimalFormat("#.##", deptDegreeCountVO.getAdCount().doubleValue() * 100D / deptDegreeCountVO.getDegreeCount().doubleValue()));
            Double bPercent = Double.valueOf(NumberUtil.decimalFormat("#.##", deptDegreeCountVO.getBdCount().doubleValue() * 100D / deptDegreeCountVO.getDegreeCount().doubleValue()));
            Double cPercent = Double.valueOf(NumberUtil.decimalFormat("#.##", deptDegreeCountVO.getCdCount().doubleValue() * 100D / deptDegreeCountVO.getDegreeCount().doubleValue()));
            deptDegreeCountVO.setAdPercent(aPercent);
            deptDegreeCountVO.setBdPercent(bPercent);
            deptDegreeCountVO.setCdPercent(cPercent);
        });
        return deptDegreeCountVOList;
    }

    @Override
    public List<ExamExportVO> listExportExams(ExamPageQuery queryParams) {
        // 格式化为数据库日期格式，避免日期比较使用格式化函数导致索引失效
        DateUtils.toDatabaseFormat(queryParams, "startTime", "endTime");
        List<ExamExportVO> list = this.baseMapper.listExportExams(queryParams);
        list.forEach(examPageVO -> {
            examPageVO.setCourseMonthStr(DateUtils.monthTranslate(examPageVO.getCourseMonth()));
            examPageVO.setHasEvaluateTimes(scoreService.countByStudentIdAndCourseId(examPageVO.getStudentId(), examPageVO.getCourseId()));
        });
        return list;
    }
}
